home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-20
/
minimuf3.zip
/
MINIMUF.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1990-10-14
|
28KB
|
913 lines
PROGRAM Minimuf_CalculateTheMuf;
{
This program calculates and displays on the screen MUF information, hour-
by-hour (GMT), for one path. A graph is drawn. After displaying the MUF
information on the screen, a hard copy can be printed.
The program is set to print MUF values from a QTH in Dallas, Texas.
The program can be customized to any QTH and the 15 pre-programmed path
choices can be modified by changing the setup file MUFSETUP.DAT.
This program is based on a BASIC program originally published in QEX of
November, 1983. The QEX program was an adaptation to the IBM PC BASIC
by John E. Anderson WD4MUO of a BASIC program published in QST of
December, 1982.
This program was adapted to TurboPascal by Keith Seabourn, 5N6SKD from
these BASIC programs found in QEX and QST. The adaptation to Pascal is
not a particularly good example of Pascal coding technique. The procedure
MinimufCalcLoop was taken directly from BASIC to Pascal and includes the
limitations of BASIC, including brief variable names and GOTO statements.
Source: QEX November, 1983 and QST December 1982, page 38.
Source of Polynomial flux to sunspot number conversion: Gilder, James H.;
Basic Computer Programs in Science and Engineering; Hayden 1980.
}
CONST
Mstr : array[1..12] of string[3] = ('JAN','FEB','MAR','APR','MAY',
'JUN','JUL','AUG','SEP','OCT','NOV','DEC');
M : array[1..12] of integer = (31,29,31,30,31,30,31,31,30,31,30,31);
PI = 3.141593;
Xstr = '===============================================================================';
Spaces = ' ;';
Yes : set of char = ['Y','y'];
No : set of char = ['N','n'];
MinMuf : integer = 7;
MaxMuf : integer = 28;
MaxPathLength = 24;
TYPE
FileNameType = string[14];
Long_String = string[255];
VAR
L1, L2, W1, W2, R0, R1, P0, P1, SF, S9, Tam, J9 : REAL;
TLat, TLon, RLat, RLon : REAL;
Ch, M0, D6, LP, TA, I, T5 : INTEGER;
Title, Line : STRING [80];
Tstr, Rstr : STRING [32];
T1, T2, X : INTEGER;
ANstr, AN1str, TAstr, Dstr : CHAR;
Plot : ARRAY [0..23, 7..28] of CHAR;
Muf : ARRAY [0..23] of REAL;
XPos, YPos : BYTE;
Path : array [1..15] of string[24];
Lat,
Lon : array [1..15] of real;
StationCall : string [11];
StationLat,
StationLon : real;
SetupFile : Text;
MaxChoices : byte;
SetupFileError : boolean;
Cntr : integer;
CSstr : string[11];
{$U+}
FUNCTION Fnacs (X : REAL) : REAL;
BEGIN
Fnacs := -ARCTAN (X / SQRT(-X * X + 1)) + 1.5708
END;
{*****************************************************************************}
{This function checks for the existence of a file of the name passed to it
by attempting to reset the file with I/O error checking switched off, and
then looking at IOResult, the built-in variable that holds I/O error
messages. This function will NOT check for files in any but the current
directory--use the "Find_First" function in GETFILE.LIB for those.
function EXISTS: boolean;
input : a filename of a TYPE declared in user program (BEFORE including this
file!)
output: true if exists else false.}
function exists(ThisFile : FileNameType):boolean;
var
tempFile : text; {We can get away with assigning a text file to ANY
filename because we aren't going to do any input/output}
begin
assign(tempFile,ThisFile);
{$I-}
reset(tempFile);
{$I+}
if IOResult = 0 then exists := true
else exists := false;
close(tempFile);
end;
{****************************************************************************}
Procedure Alert(Message : Long_String);{* This routine prints MESSAGE to the*}
{* screen and makes an obnoxious *}
Var {* noise for about 1 second *}
I : Integer; {*************************************}
i1,i2,i3,i4 : integer;
begin
write(Message);
for i4 := 10 downto 1 do
begin
i2 := 250 + i4 * 25;
for i3 := 2 downto 1 do
begin
for i1 := 1 to 30 - i3 * 2 do
begin
sound(i1 + i2 + i3 * 2);
delay(2);
end;
delay(5);
i2 := i2 + 30;
end;
nosound;
end;
end;
PROCEDURE Initialize;
BEGIN
R0 := PI / 180.0;
P1 := 2.0 * PI;
R1 := 180.0 / PI;
P0 := PI / 2.0;
TITLE := COPY(Spaces,1,36) + 'MINIMUF' + COPY(Spaces,1,36);
AN1str := '*';
END;
PROCEDURE ReadSetupFileData;
{Reads the file MUFSETUP.DAT on the default drive. Returns
StationCall : string[11] : callsign of station
StationLat,
StationLon : real : latitude, longitude for station
Path : array [1..15] of string[24] : path options
Lat : array [1..15] of real : latitude for each path option
Lon : array [1..15] of real : longitude for each path option
SetupFileError : boolean : TRUE if an error is found in the file
FALSE if data is good
}
var
OneChar : char;
LatStr,
LonStr : string[7];
ConvError : integer;
I, J : integer;
begin
SetupFileError := False;
assign(SetupFile,'MUFSETUP.DAT');
if exists('MUFSETUP.DAT') then
begin
reset(SetupFile);
{Get station call, station latitude, station longitude}
StationCall := '';
I := 1;
repeat
read(SetupFile,OneChar);
if OneChar<>';' then StationCall := StationCall + OneChar;
I := I + 1;
until ((OneChar=';') or (I>(SizeOf(StationCall)-1)) or (OneChar=^M));
if ((OneChar <> ';') or (I>(SizeOf(StationCall)-1)) or (OneChar=^M)) then
begin
SetupFileError := True;
writeln('An error occurred while reading setup file.');
writeln('The Station Call "',StationCall,'" is more than ',
(SizeOf(StationCall)-1):2,' characters');
writeln('or latitude or longitude data is missing.');
writeln;
end;
{Parse for Latitude}
if not SetupFileError then
begin
I := 1;
LatStr := '';
repeat
read(SetupFile,OneChar);
if OneChar<>';' then LatStr := LatStr + OneChar;
I := I + 1;
until ((OneChar=';') or (I>(SizeOf(LatStr)-1)) or (OneChar=^M));
val(LatStr,StationLat,ConvError);
if (Length(LatStr)=0) or (OneChar<>';') or (I>(SizeOf(LatStr)-1))
or (ConvError<>0) then
begin
SetupFileError := True;
writeln('An error occurred while reading setup file.');
writeln('The latitude "',LatStr,'" is not in the correct ',
'format or has too many digits.');
writeln;
end;
end;
{Parse for Longitude}
if not SetupFileError then
begin
I := 1;
LonStr := '';
repeat
read(SetupFile,OneChar);
if (OneChar<>';') and (OneChar<>^M) then LonStr := LonStr + OneChar;
I := I + 1;
until (OneChar=^M) or (I>(SizeOf(LonStr)-1));
val(LonStr,StationLon,ConvError);
if ((Length(LonStr)=0) or (I>(SizeOf(LonStr)-1)) or (ConvError<>0)) then
begin
SetupFileError := True;
writeln('An error occurred while reading setup file.');
writeln('The longitude "',LonStr,'" is not in the correct ',
'format or has too many digits.');
writeln;
end;
end;
read(SetupFile,OneChar); {skip the Line Feed}
{Read remainder of SetupFile and parse for path options}
I := 1;
while not (SetupFileError or EOF(SetupFile)) do
begin
Path[I] := '';
Lat[I] := 0.0;
Lon[I] := 0.0;
LatStr := '';
LonStr := '';
J := 0;
repeat
J := J + 1;
read(SetupFile,OneChar);
if OneChar<>';' then Path[I] := Path[I] + OneChar;
until (OneChar=';') or (J>MaxPathLength+1) or (OneChar = ^M);
if (OneChar <> ';') or (J>MaxPathLength+1) then
begin
SetupFileError := True;
if (J > MaxPathLength) or (OneChar = ^M) then
begin
writeln('An error occurred while reading setup file.');
writeln('The path "',Path[I],'" is more than ',
MaxPathLength:2,' characters');
writeln('or latitude or longitude data is missing.');
writeln;
end;
end;
if not SetupFileError then
begin
J := 1;
repeat
read(SetupFile,OneChar);
if (OneChar<>';') and (OneChar<>^M) then LatStr := LatStr + OneChar;
J := J + 1;
until (OneChar=';') or (J>(SizeOf(LatStr)-1)) or (OneChar=^M);
val(LatStr,Lat[I],ConvError);
if (Length(LatStr)<=0) or (OneChar<>';') or (J>(SizeOf(LatStr)-1))
or (ConvError<>0) then
begin
SetupFileError := True;
writeln('An error occurred while reading setup file.');
writeln('The latitude "',LatStr,'" in the path "',Path[I],'"');
writeln('is not in the correct format or has too many digits.');
writeln;
end;
end;
if not SetupFileError then
begin
J := 1;
repeat
read(SetupFile,OneChar);
if (OneChar<>';') and (OneChar<>^M) then LonStr := LonStr + OneChar;
J := J + 1;
until (OneChar=^M) or (J>(SizeOf(LonStr))) or (EOF(SetupFile));
val(LonStr,Lon[I],ConvError);
if (Length(LonStr) <=0) or (J > (SizeOf(LonStr)))
or (ConvError <> 0) then
begin
SetupFileError := True;
writeln('An error occurred while reading setup file.');
writeln('The longitude "',LonStr,'" in the path "',Path[I],'"');
writeln('is not in the correct format or has too many digits.');
writeln;
end;
end;
I := I + 1;
read(SetupFile,OneChar); {skip LineFeed}
end; {while not(SetupFileError or EOF(SetupFile)}
if SetupFileError then
begin
gotoxy(1,WhereY+1);
alert('An error occurred while reading setup file.');
writeln;
writeln('Use an ASCII word processor to carefully check the file');
writeln('MUFSETUP.DAT then try again.');
write('Press any key to continue...');
repeat until keypressed;
MaxChoices := 0;
end
else
MaxChoices := I - 1;
end {if SetupFile exists}
else {if SetupFile does not exist}
begin
alert('MUFSETUP.DAT cannot be found. Program aborting.');
end;
end; {procedure ReadSetupFileData}
PROCEDURE PrintScreenHeader;
BEGIN
CLRSCR;
TEXTCOLOR(Black);
TEXTBACKGROUND(LightGray);
WRITELN (Xstr);
WRITELN (TITLE);
WRITELN (Xstr);
TEXTCOLOR(LightGray);
TEXTBACKGROUND(Black);
END;
PROCEDURE DisplayOptionMenu;
BEGIN
WRITELN;
WRITELN ('Path Options');
WRITELN;
FOR I := 1 TO MaxChoices do
WRITELN(I:3,' ',CSstr,' ',Path[I]);
WRITELN (' 16 ', CSstr, ' TO A SPECIFIED POINT');
WRITELN (' 17 ','BETWEEN SPECIFIED POINTS');
END;
PROCEDURE GetTransmitterLatLon;
BEGIN
REPEAT
WRITELN;
WRITE ('TRANSMITTER LATITUDE ("-" for East)?');
READLN (L1);
IF (L1 < -90.0) OR (L1 > 90.0) THEN
WRITELN ('INVALID LATITUDE. MUST BE IN RANGE (-90 TO +90).');
UNTIL (L1 >= -90.0) AND (L1 <= 90.0);
REPEAT
WRITE ('TRANSMITTER LONGITUDE ("-" for South)?');
READLN (W1);
IF (W1 < -360.0) OR (W1 > 360.0) THEN
WRITELN ('INVALID LONGITUDE. MUST BE IN RANGE (-360 TO +360).');
UNTIL (W1 >= -360.0) AND (W1 <= 360.0);
END; {Procedure GetTransmitterLatLon}
PROCEDURE GetReceiverLatLon;
BEGIN
REPEAT
WRITELN;
WRITE ('RECEIVER LATITUDE ("-" for East)?');
READLN (L2);
IF (L2 < -90.0) OR (L2 > 90.0) THEN
WRITELN ('INVALID LATITUDE. MUST BE IN RANGE (-90 TO +90).');
UNTIL (L2 >= -90.0) AND (L2 <= 90.0);
REPEAT
WRITE ('RECEIVER LONGITUDE ("-" for South)?');
READLN (W2);
IF (W2 < -360.0) OR (W2 > 360.0) THEN
WRITELN ('INVALID LONGITUDE. MUST BE IN RANGE (-360 TO +360).');
UNTIL (W2 >= -360.0) AND (W2 <= 360.0);
END; {Procedure GetReceiverLatLon}
PROCEDURE GetLatitudeLongitude;
BEGIN
Tstr := CSstr;
CASE Ch OF
1..15 : BEGIN
L1 := StationLat;
W1 := StationLon;
L2 := Lat[Ch];
W2 := Lon[Ch];
Rstr := Path[Ch];
END;
16: BEGIN
L1 := StationLat;
W1 := StationLon;
Rstr := 'RECEIVER';
GetReceiverLatLon;
END;
17: BEGIN
Tstr := 'TRANSMITTER';
Rstr := 'RECEIVER';
GetTransmitterLatLon;
GetReceiverLatLon;
END;
END; {Case}
TLat := L1;
TLon := W1;
RLat := L2;
RLon := W2;
END; {Procedure GetLatitudeLongitude}
PROCEDURE GetDayMonth;
BEGIN
REPEAT
WRITELN;
WRITELN ('Input day and month as (day month)? ');
READLN (D6,M0);
IF (M0<1) OR (M0>12) THEN WRITELN ('Invalid Month. Must be in range (1 to 12)');
IF (D6<1) OR (D6>M[M0]) THEN WRITELN ('Invalid Day. Must be in range (1 to ', M[M0], ')');
UNTIL (M0>=1) AND (M0<=12) AND (D6>=1) AND (D6<=M[M0]);
END;
PROCEDURE SolarFluxToSunSpot;
BEGIN
S9 := -103.7767 + 1.797429 * SF - (3.384356E-03)*SF*SF + (4.525515E-06)*SF*SF*SF;
S9 := INT (100 * S9 +0.5)/100;
END;
PROCEDURE SunSpotData;
BEGIN
WRITELN;
WRITE ('STATE SOURCE OF SOLAR ACTIVITY - S=sunspot no. F=solar flux ? ');
READLN (AN1str);
IF (AN1str='S') OR (AN1str='s') THEN
BEGIN
REPEAT
WRITELN;
WRITE ('INPUT SMOOTHED INTERNATIONAL SUNSPOT NUMBER= ? ');
READLN (S9);
IF S9<0 THEN WRITELN ('INVALID SUNSPOT NUMBER. MUST BE NON-NEGATIVE.');
UNTIL (S9 >= 0.0);
END
ELSE
BEGIN
REPEAT
WRITE ('INPUT SMOOTHED MEAN 10.7cm SOLAR FLUX ? ');
READLN (SF);
IF (SF<65) THEN WRITELN ('INVALID FLUX NUMBER, MUST BE GREATER THAN 65.');
IF (SF>245) THEN WRITELN ('RESULTS MAY BE INACCURATE FOR FLUX GREATER THAN 245.');
UNTIL SF>=65;
SolarFluxToSunSpot;
WRITELN ('A FLUX OF ', SF:5:1, ' EQUATES TO A SUNSPOT NUMBER OF ', S9:3:0);
END;
END; {Procedure SunSpotData}
PROCEDURE HardCopyFlag;
BEGIN
TEXTBACKGROUND(LightGray);
TEXTCOLOR(Black);
REPEAT
WRITE ('Want Printout(Y/N)?',^G,^G,^G);
TEXTBACKGROUND(Black);
TEXTCOLOR(LightGray);
WRITE (' ');
READ (ANstr);
IF (ANstr IN Yes) THEN LP := 1;
IF (ANstr IN No) THEN LP := 0;
UNTIL (ANstr IN Yes) OR (ANstr IN No);
END; {Procedure HardCopyFlag}
PROCEDURE ThresholdFlag;
BEGIN
REPEAT
WRITELN;
WRITELN;
WRITE ('WANT FLAG ON MUF ABOVE GIVEN FREQ (Y or N)? ');
READLN (TAstr);
IF (TAstr IN Yes) THEN
BEGIN
TA:=1;
WRITE ('SPECIFY FREQ IN MHZ.? ');
READLN (Tam);
END;
IF (TAstr IN No) THEN TA:=0;
UNTIL (TAstr IN Yes) OR (TAstr IN No);
END;
PROCEDURE HardCopyHeader;
BEGIN
WRITELN(LST,' 1 3 5 7 9 11 13 15 17 19 21 23');
END;
PROCEDURE HardCopyFooter;
BEGIN
WRITELN(LST,' 1 3 5 7 9 11 13 15 17 19 21 23 ');
END;
PROCEDURE HardCopyDataPrint;
BEGIN
T5 := MaxMuf;
WRITE(LST,T5:2, '|');
FOR I:=0 TO 23 DO WRITE(LST,' ', Plot[I,T5]);
WRITELN(LST,' Date: ', D6:2, ' ', Mstr[M0]);
T5 := T5 - 1;
WRITE(LST,T5:2, '|');
FOR I := 0 TO 23 DO WRITE(LST,' ', Plot[I,T5]);
WRITELN(LST);
T5 := T5 - 1;
WRITE(LST,T5:2, '|');
FOR I := 0 TO 23 DO WRITE(LST,' ', Plot[I,T5]);
WRITELN(LST,'Sunspot Number = ', S9:3:0);
T5 := T5 - 1;
WRITE(LST,T5:2, '|');
FOR I := 0 TO 23 DO WRITE(LST,' ', Plot[I,T5]);
WRITELN(LST);
T5 := T5 - 1;
WRITE(LST,T5:2, '|');
FOR I := 0 TO 23 DO WRITE(LST,' ', Plot[I,T5]);
WRITELN(LST,'From: ', COPY(Tstr, 1, 22));
T5 := T5 - 1;
WRITE(LST,T5:2, '|');
FOR I := 0 TO 23 DO WRITE(LST,' ', Plot[I,T5]);
WRITELN(LST,' Lat: ', TLat:3:0, ' Lon: ',TLon:4:0);
T5 := T5 - 1;
WRITE(LST,T5:2, '|');
FOR I := 0 TO 23 DO WRITE(LST,' ', Plot[I,T5]);
WRITELN(LST,'To: ', COPY(Rstr, 1, 24));
T5 := T5 - 1;
WRITE(LST,T5:2, '|');
FOR I := 0 TO 23 DO WRITE(LST,' ', Plot[I,T5]);
WRITELN(LST,' Lat: ', RLat:3:0, ' Lon: ', RLon:4:0);
T5 := T5 - 1;
WRITE(LST,T5:2, '|');
FOR I := 0 TO 23 DO WRITE(LST,' ', Plot[I,T5]);
WRITELN(LST);
T5 := T5 - 1;
WRITE(LST,T5:2, '|');
FOR I := 0 TO 23 DO WRITE(LST,' ', Plot[I,T5]);
WRITELN(LST,' UTC MUF UTC MUF');
FOR T5 := MaxMuf-10 DOWNTO MinMuf DO
BEGIN
T1 := (MaxMuf-10) - T5;
T2 := T1 + 12;
WRITE(LST,T5:2,'|');
FOR I := 0 TO 23 DO WRITE(LST,' ',Plot[I,T5]);
WRITELN(LST,' ',T1:2,' ',Muf[T1]:4:1,' ',T2:2,' ',Muf[T2]:4:1);
END; {T5 := MaxMuf-10 DOWNTO MinMuf-12}
END;
FUNCTION SGN(X : REAL) :REAL;
{Simulates BASIC function SGN}
BEGIN
IF X < 0.0 THEN SGN := -1.0;
IF X = 0.0 THEN SGN := 0.0;
IF X > 0.0 THEN SGN := 1.0;
END;
FUNCTION POWER(X, Y : REAL) :REAL;
{Raises X to the Yth power}
{Simulates BASIC X^Y or FORTRAN X**Y}
BEGIN
POWER := EXP(Y * LN(X));
END;
PROCEDURE MinimufCalcLoop;
LABEL
Label198, Label214, Label215, Label223, Label228, Label234;
CONST
MIN_EXP = -88.02969;
VAR
K7, G1, K6, K5, P, Q, A, B, C, D, W0, L0 : REAL;
T6, Y1, Y2, K1, K8, K9, G0, M9, T, T4, C0, T9 : REAL;
G9, G8, U, G7, G2, U1, EXP_U, EXP_U1, EXP_K9A, EXP_K9B : REAL;
BEGIN
K7 := SIN(L1) * SIN(L2) + COS(L1) * COS(L2) * COS(W2-W1);
IF K7 < -1.0 THEN K7 := -1.0;
IF K7 > 1.0 THEN K7 := 1.0;
G1 := Fnacs(K7);
K6 := 1.59 * G1;
IF K6 < 1.0 THEN K6 := 1.0;
K5 := 1.0/K6;
J9 := 100.0;
K1 := 1.0/(2.0*K6);
WHILE (SGN(0.9999-1.0/K6)*K1) <= (SGN(0.9999-1.0/K6)*(1.0 - 1.0/(2.0*K6))) DO
BEGIN
IF K5 <> 1.0 THEN K5 := 0.5;
P := SIN(L2);
Q := COS(L2);
A := (SIN(L1) - P*COS(G1)) / (Q * SIN(G1));
B := G1 * K1;
C := P * COS(B) + Q * SIN(B) * A;
D := (COS(B) - C * P) / (Q * SQRT(1 - C*C));
IF D < -1.0 THEN D := -1.0;
IF D > 1.0 THEN D := 1.0;
D := Fnacs(D);
W0 := W2 + SGN(SIN(W1-W2))*D;
IF W0 < 0.0 THEN W0 := W0+P1;
IF W0 >= P1 THEN W0 := W0-P1;
IF C < -1.0 THEN C := -1.0;
IF C > 1.0 THEN C := 1.0;
L0 := P0 - Fnacs(C);
Y1 := 0.0172 * (10 + (M0-1)*30.4 + D6);
Y2 := 0.409 * COS(Y1);
K8 := 3.82*W0 + 12.0 + 0.13*(SIN(Y1) + 1.2*SIN(2*Y1));
K8 := K8 - 12*(1 + SGN(K8-24.0))*SGN(ABS(K8-24.0));
IF COS(L0+Y2) > -0.26 THEN GOTO Label198;
K9 := 0.0;
G0 := 0.0;
M9 := 2.5 * G1 * K5;
IF M9 > P0 THEN M9 := P0;
M9 := SIN(M9);
M9 := 1.0 + 2.5 * M9 * SQRT(M9);
GOTO Label223;
Label198:
K9 := (-0.26 + SIN(Y2)*SIN(L0)) / (COS(Y2)*COS(L0) + 9.999999E-04);
K9 := 12.0 - ARCTAN(K9/SQRT(ABS(1.0 - K9*K9))) * 7.639437;
T := K8 - K9/2.0 + 12.0*(1-SGN(K8-K9/2))*SGN(ABS(K8-K9/2));
T4 := K8 + K9/2 - 12.0*(1+SGN(K8+K9/2-24.0))*SGN(ABS(K8+K9/2-24.0));
C0 := ABS(COS(L0+Y2));
T9 := 9.7 * POWER(C0,9.600001);
IF T9 < 0.1 THEN T9 := 0.1;
M9 := 2.5 * G1 * K5;
IF M9 > P0 THEN M9 := P0;
M9 := SIN(M9);
M9 := 1.0 + 2.5 * M9 * SQRT(M9);
IF T4 < T THEN GOTO Label214;
IF ((T5-T) * (T4-T5)) > 0.0 THEN GOTO Label215;
GOTO Label228;
Label214:
IF ((T5-T4) * (T-T5)) > 0.0 THEN GOTO Label228;
Label215:
T6 := T5 + 12.0*(1.0+SGN(T-T5))*SGN(ABS(T-T5));
G9 := PI*(T6-T)/K9;
G8 := PI*T9/K9;
U := (T-T6)/T9;
IF U >= MIN_EXP THEN EXP_U := EXP(U) ELSE EXP_U := 0.0;
IF (-K9/T9) >= MIN_EXP THEN EXP_K9A := EXP(-K9/T9) ELSE EXP_K9A := 0.0;
IF ((K9-24.0)/2.0) >= MIN_EXP THEN EXP_K9B := EXP((K9-24.0)/2.0) ELSE EXP_K9B := 0.0;
G0 := C0*(SIN(G9) + G8*(EXP_U-COS(G9)))/(1.0 + G8*G8);
G7 := C0 * (G8*(EXP_K9A+1.0)) * EXP_K9B / (1.0 + G8*G8);
IF G0 < G7 THEN G0 := G7;
Label223:
G2 := (1.0+S9/250.0) * M9 * SQRT(6.0+58.0*SQRT(G0));
IF ((K9-24.0)/3.0) >= MIN_EXP THEN EXP_K9B := EXP((K9-24.0)/3.0) ELSE EXP_K9B := 0.0;
G2 := G2*(1.0-0.1*EXP_K9B);
G2 := G2*(1.0+(1.0-SGN(L1)*SGN(L2))*0.1);
G2 := G2*(1.0-0.1*(1.0+SGN(ABS(SIN(L0))-COS(L0))));
GOTO Label234;
Label228:
T6 := T5 + 12.0*(1.0+SGN(T4-T5))*SGN(ABS(T4-T5));
G8 := PI*T9/K9;
U := (T4-T6)/2.0;
U1 := -K9/T9;
IF U >= MIN_EXP THEN EXP_U := EXP(U) ELSE EXP_U := 0.0;
IF U1 >= MIN_EXP THEN EXP_U1 := EXP(U1) ELSE EXP_U1 := 0.0;
G0 := C0*(G8*(EXP_U1+1.0))*EXP_U/(1.0 + G8*G8);
GOTO Label223;
Label234:
IF G2 < J9 THEN J9 := G2;
K1 := K1 + 0.9999-1.0/K6;
END; {While}
END; {Procedure}
PROCEDURE DataPrint;
BEGIN
T5 := MaxMuf;
WRITE(T5:2, '|');
FOR I:=0 TO 23 DO WRITE(' ', Plot[I,T5]);
WRITELN(' Date: ', D6:2, ' ', Mstr[M0]);
T5 := T5 - 1;
WRITE(T5:2, '|');
FOR I := 0 TO 23 DO WRITE(' ', Plot[I,T5]);
WRITELN;
T5 := T5 - 1;
WRITE(T5:2, '|');
FOR I := 0 TO 23 DO WRITE(' ', Plot[I,T5]);
WRITELN('Sunspot Number = ', S9:3:0);
T5 := T5 - 1;
WRITE(T5:2, '|');
FOR I := 0 TO 23 DO WRITE(' ', Plot[I,T5]);
WRITELN;
T5 := T5 - 1;
WRITE(T5:2, '|');
FOR I := 0 TO 23 DO WRITE(' ', Plot[I,T5]);
WRITELN('From: ', COPY(Tstr, 1, 22));
T5 := T5 - 1;
WRITE(T5:2, '|');
FOR I := 0 TO 23 DO WRITE(' ', Plot[I,T5]);
WRITELN(' Lat: ', TLat:3:0, ' Lon: ',TLon:4:0);
T5 := T5 - 1;
WRITE(T5:2, '|');
FOR I := 0 TO 23 DO WRITE(' ', Plot[I,T5]);
WRITELN('To: ', COPY(Rstr, 1, 24));
T5 := T5 - 1;
WRITE(T5:2, '|');
FOR I := 0 TO 23 DO WRITE(' ', Plot[I,T5]);
WRITELN(' Lat: ', RLat:3:0, ' Lon: ', RLon:4:0);
T5 := T5 - 1;
WRITE(T5:2, '|');
FOR I := 0 TO 23 DO WRITE(' ', Plot[I,T5]);
WRITELN;
T5 := T5 - 1;
WRITE(T5:2, '|');
FOR I := 0 TO 23 DO WRITE(' ', Plot[I,T5]);
WRITELN(' UTC MUF UTC MUF');
FOR T5 := MaxMuf-10 DOWNTO MinMuf DO
BEGIN
T1 := (MaxMuf-10) - T5;
T2 := T1 + 12;
WRITE(T5:2,'|');
FOR I := 0 TO 23 DO WRITE(' ',Plot[I,T5]);
WRITELN(' ',T1:2,' ',Muf[T1]:4:1,' ',T2:2,' ',Muf[T2]:4:1);
END; {T5 := MaxMuf-10 DOWNTO MinMuf-12}
END;
PROCEDURE PrintGraphHeader;
BEGIN
WRITELN(' 1 3 5 7 9 11 13 15 17 19 21 23');
END;
PROCEDURE PrintGraphFooter;
BEGIN
WRITE (' 1 3 5 7 9 11 13 15 17 19 21 23 ');
END;
PROCEDURE ClearPlotArray;
BEGIN
{Initialize plotting array to blanks}
FOR I := 0 TO 23 DO
BEGIN
FOR T5 := (MinMuf+1) TO (MaxMuf-1) DO Plot[I,T5] := ' ';
END;
FOR I := 0 TO 23 DO
BEGIN
Plot[I,MinMuf] := '=';
Plot[I,MaxMuf] := '=';
Plot[I,14] := '-';
Plot[I,21] := '-';
END;
END;
{MAIN PROGRAM}
BEGIN
Initialize;
ReadSetupFileData;
IF not SetupFileError then
BEGIN
CSstr := StationCall;
REPEAT
BEGIN
REPEAT
PrintScreenHeader;
DisplayOptionMenu;
ClearPlotArray;
WRITE ('CHOICE? ');
READLN (Ch);
IF (Ch<1) OR (Ch>17) THEN
BEGIN
CLRSCR;
GOTOXY(30,12);
WRITELN ('BAD CHOICE NUMBER',^G);
DELAY (500);
END;
UNTIL (Ch>=1) AND (Ch<=17);
{If this is the first time through, then get date and sunspot info}
{If this is the first time, AN1str='*' from Initialize}
{If we have been through before, AN1str = S,s,F,f from SunSpotData}
IF AN1str='*' THEN
BEGIN
CLRSCR;
PrintScreenHeader;
GetDayMonth;
SunSpotData;
ThresholdFlag;
END;
GetLatitudeLongitude;
CLRSCR;
PrintScreenHeader;
GOTOXY(25,12);
WRITE('Calculating the MUF for **00z');
L1 := L1 * R0;
W1 := W1 * R0;
L2 := L2 * R0;
W2 := W2 * R0;
FOR T5 := 0 TO 23 DO
BEGIN
GOTOXY(49,12);
WRITE(T5:2);
MinimufCalcLoop;
IF TA = 0 THEN Dstr := '*';
IF TA = 1 THEN
BEGIN
IF J9 >= Tam THEN Dstr := '*'
ELSE Dstr := '.'
END;
I := ROUND(J9);
{Set a floor of <MinMuf>MHz and a ceiling of <MaxMuf>MHz for the plot}
IF I < MinMuf THEN
BEGIN
I := MinMuf;
Dstr := '@';
END;
IF I > MaxMuf THEN
BEGIN
I := MaxMuf;
Dstr := '@';
END;
Muf[T5] := J9;
Plot[T5,I] := Dstr;
END; {T5 := 0 TO 23}
CLRSCR;
PrintGraphHeader;
DataPrint;
PrintGraphFooter;
XPos := WhereX;
YPos := WhereY;
HardCopyFlag;
IF LP = 1 THEN
BEGIN
HardCopyHeader;
HardCopyDataPrint;
HardCopyFooter;
END;
GOTOXY(XPos,YPos);
CLREOL;
TEXTBACKGROUND(LightGray);
TEXTCOLOR(Black);
WRITE ('Plot another (Y/N)?', ^G, ^G, ^G);
TEXTBACKGROUND(Black);
TEXTCOLOR(LightGray);
WRITE (' ');
READLN (ANstr);
END; {Repeat Main Loop}
UNTIL (ANstr IN No);
END; {If there is no SetupFileError}
END.